#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.common.component.service;

import ${package}.common.utils.SnowFlakeUtil;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Description: 内存存储
 *
 * @author wupanhua
 * @date 2019/8/6 15:28
 *
 * <pre>
 *              ${copyright}
 *      Copyright (c) 2019. All Rights Reserved.
 * </pre>
 */
@Slf4j
@Component
@AllArgsConstructor
public class RedisService<K, V> {

    /**
     * RedisTemplate
     */
    private RedisTemplate<String, Object> redisTemplate;

    private StringRedisTemplate stringRedisTemplate;

    /**
     * Description:
     * <set值>
     * @author wupanhua
     * @date 15:45 2019/8/8
     * @param key 1
     * @param value 2
     * @return boolean
     **/
    public boolean set (String key, Object value) {

        return this.set(key, value, null);
    }

    /**
     * Description:
     * <set 一个带时间的key-value>
     * @author wupanhua
     * @date 15:46 2019/8/8
     * @param key 1
     * @param value 2
     * @param expireTime 过期时间 s
     * @return boolean
     **/
    public boolean set(final String key, Object value, Long expireTime) {

        boolean result = false;

        try {
            redisTemplate.opsForValue().set(key, value);
            if(null!=expireTime) {
                redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            }
            result = true;
        } catch (Exception e) {
            log.error("error info ",e);
        }

        return result;
    }

    /**
     * Description:
     * <获取值>
     * @author wupanhua
     * @date 15:46 2019/8/8
     * @param key 1
     * @return java.lang.Object
     **/
    public Object get(String key) {
	    if (null == key) {
		    return null;
	    }
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * Description:
     * <移除键值对>
     * @author wupanhua
     * @date 15:46 2019/8/8
     * @param key 1
     **/
    public void remove(String key) {

        if (StringUtils.isNotBlank(key)) {
            try {
                redisTemplate.opsForValue().getOperations().delete(key);
            } catch (Exception e) {
                log.error("redis remove key '{}' error", key, e);
            }
        }
    }

    /**
     * Description:获取带有指定前缀的所有key
     * <>
     * @author songcx
     * @date 10:29 2021/3/3
     * @param prefix 1
     * @return java.util.Set<java.lang.String>
     **/
    public Set<String> getPrefixKeyList(String prefix){
        return redisTemplate.keys(prefix);
    }

    /**
     * Description:向指定list尾部添加数据
     * <>
     * @author songcx
     * @date 10:32 2021/3/3
     * @param key 1
     * @param value 2
     **/
    public void listRightPush(String key,Object value){
        redisTemplate.opsForList().rightPush(key,value);
    }

    /**
     * Description:获取list中的最后一个值
     * <>
     * @author songcx
     * @date 10:39 2021/3/3
     * @param key 1
     * @return java.lang.Object
     **/
    public Object getListLastValue(String key){
        if(Boolean.TRUE.equals(redisTemplate.hasKey(key))){
            return redisTemplate.opsForList().index(key,-1);
        }else {
            return null;
        }
    }

    /**
     * Description:获取list的长度
     * <>
     * @author songcx
     * @date 10:40 2021/3/3
     * @param key 1
     * @return java.lang.Long
     **/
    public Long getListSize(String key){
        return redisTemplate.opsForList().size(key);
    }

    /**
     * Description:获取分布式锁
     * <>
     * @author songcx
     * @date 14:31 2021/3/3
     * @param key 1
     * @param expireTime 2
     * @return boolean
     **/
    public boolean getLock(String key,Long expireTime){
        if(Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key,SnowFlakeUtil.getID()))){
            redisTemplate.expire(key,expireTime,TimeUnit.MINUTES);
            return true;
        }else {
            return false;
        }
    }

    /**
     * Description:设置key的过期时间
     * <>
     * @author songcx
     * @date 11:17 2021/3/4
     * @param key 1
     * @param expireTime 2
     **/
    public void setExpireTime(String key,Long expireTime){
        redisTemplate.expire(key,expireTime,TimeUnit.SECONDS);
    }

    /**
     * Description:从左到右的获取一个list数据
     * <>
     * @author songcx
     * @date 9:51 2021/3/5
     * @param key 1
     * @return java.lang.Object
     **/
    public Object getListOnLeft(String key){
        return redisTemplate.opsForList().range(key,0,-1);
    }

    /**
     * Description:向set中添加数据
     * <>
     * @author songcx
     * @date 15:35 2021/3/8
     * @param key 1
     * @param value 2
     **/
    public void setSet(String key,Object value){
        redisTemplate.opsForSet().add(key,value);
    }

    /**
     * Description:获取指定set中的值的数量
     * <>
     * @author songcx
     * @date 15:36 2021/3/8
     * @param key 1
     * @return java.lang.Long
     **/
    public Long getSetSize(String key){
        return redisTemplate.opsForSet().size(key);
    }
}
